﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Data;
using System.Globalization;

namespace Relay.UI.Controls.Docking.Primitives {
    /// <summary>
    /// Provides a panel which horizontally stacks a row of buttons like a tab control, resizing
    /// them as necessary to fit in the allotted space.
    /// </summary>
    public class DockWindowTabPanel : Panel {
        #region Constructor
        /// <summary>
        /// Initializes the <see cref="DockWindowTabPanel"/> class.
        /// </summary>
        static DockWindowTabPanel() {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DockWindowTabPanel),
                new FrameworkPropertyMetadata(typeof(DockWindowTabPanel)));
        }
        #endregion

        #region Private Methods
        private double GetTotalWidth() {
            double w = 0;

            foreach (DockWindow window in InternalChildren)
                w += window.DesiredSize.Width;

            return w;
        }
        #endregion

        #region Overrides
        protected override Size MeasureOverride(Size availableSize) {
            Size newSize = new Size(double.IsPositiveInfinity(availableSize.Width) ? 0 : availableSize.Width,
                            double.IsPositiveInfinity(availableSize.Height) ? 0 : availableSize.Height);
            Size finalSize = new Size();
            double total = 0;

            // Possible evil hackery, calling Measure twice? I see no way around it, first to get the size that
            // all the buttons really want, then to tell them the actual size they can have
            foreach (UIElement element in InternalChildren) {
                element.Measure(availableSize);
                total += element.DesiredSize.Width;
            }

            double ratio = Math.Min(1.0, newSize.Width / total);

            foreach (UIElement element in InternalChildren) {
                element.Measure(new Size(element.DesiredSize.Width * ratio, availableSize.Height));
                finalSize.Height = Math.Max(finalSize.Height, element.DesiredSize.Height);
            }

            newSize.Height = finalSize.Height;
            return newSize;
        }

        protected override Size ArrangeOverride(Size finalSize) {
            double x = 0;
            double ratio = finalSize.Width / GetTotalWidth();

            foreach (DockWindow window in InternalChildren) {
                double width = window.DesiredSize.Width * Math.Min(1.0, ratio);
                Rect tabRect = new Rect(x, 0, width, DesiredSize.Height);
                window.Arrange(tabRect);
                x += width;
            }

            return finalSize;
        }
        #endregion
    }
}
